package chapter12_并发程序的测试.正确性测试;

import annotation.GuardedBy;
import annotation.ThreadSafe;

import java.util.concurrent.Semaphore;

@ThreadSafe
public class BoundedBuffer<E> {
    private final Semaphore avaliableItems, avaliableSpaces;
    @GuardedBy("this")
    private final E[] items;
    @GuardedBy("this")
    private int putPosition = 0, takePosition = 0;

    public BoundedBuffer(int capacity) {
        this.avaliableItems = new Semaphore(0);
        this.avaliableSpaces = new Semaphore(capacity);
        this.items = (E[]) new Object[capacity];
    }

    public boolean isEmpty() {
        return avaliableItems.availablePermits() == 0;
    }

    public boolean isFull() {
        return avaliableSpaces.availablePermits() == 0;
    }

    public void put(E x) throws InterruptedException {
        avaliableSpaces.acquire(); //当容器满时阻塞
        doInsert(x);
        avaliableItems.release();
    }

    public E take() throws InterruptedException {
        avaliableItems.acquire(); //当容器空时阻塞
        E item = doExtract();
        avaliableSpaces.release();
        return item;
    }

    private synchronized void doInsert(E x) {
        int i = putPosition;
        items[i] = x;
        putPosition = (++i == items.length) ? 0 : i;
    }

    private synchronized E doExtract() {
        int i = takePosition;
        E x = items[i];
        items[i] = null;
        takePosition = (++i == items.length) ? 0 : i;
        return x;
    }
}
